
using System;
using System.Collections.Generic;
using System.IO;
namespace Yahtzee.Game
{
    public class Spel
    {

        private BovensteSectie bovensteSectie;

        private OndersteSectie ondersteSectie;

        private Stack<Beurt> beurten;

        public Spel()
        {
            bovensteSectie = new BovensteSectie();
            ondersteSectie = new OndersteSectie();
            beurten = new Stack<Beurt>();
        }

        public void gooiMetDobbelstenen()
        {
            laatsteBeurt().gooiMetDobbelstenen();
        }

        public int[] geefOgen()
        {
            return laatsteBeurt().geefOgen();
        }

        public bool[] geefVast()
        {
            return laatsteBeurt().geefVast();
        }

        public BovensteSectie getBovensteSectie()
        {
            return bovensteSectie;
        }

        public OndersteSectie getOndersteSectie()
        {
            return ondersteSectie;
        }

        public void zetDobbelstenenVast(bool[] zetvast)
        {
            laatsteBeurt().zetVast(zetvast);
        }

        public void volgendeBeurt()
        {
            int volgendeBeurt = bepaalVolgendeBeurtnr();
            beurten.Push(new Beurt(volgendeBeurt));
        }

        private int bepaalVolgendeBeurtnr()
        {
            if (!spelNietAfgelopen())
            {
                throw new Exception("Alle beurten zijn gebruikt, het spel is afgelopen");
            }
            if (beurten.Count < 1)
            {
                return 1;
            }
            Beurt vorigeBeurt = laatsteBeurt();
            if (!vorigeBeurt.isBeurtAfgelopen())
            {
                throw new Exception("De huidige beurt is nog niet afgelopen");
            }
            return vorigeBeurt.getBeurtnr() + 1;
        }

        private Beurt laatsteBeurt()
        {
            return beurten.Peek();
        }

        public Scorecombinatie[] geefCombinaties()
        {
            Scorecombinatie[] sectieboven = bovensteSectie.geefCombinaties();
            Scorecombinatie[] sectieonder = ondersteSectie.geefCombinaties();
            Scorecombinatie[] combinaties = new Scorecombinatie[sectieboven.Length + sectieonder.Length];
            Array.Copy(sectieboven, 0, combinaties, 0, sectieboven.Length);
            Array.Copy(sectieonder, 0, combinaties, sectieboven.Length, sectieonder.Length);
            return combinaties;
        }


        public Scorecombinatie[] geefVrijeCombinaties()
        {
            List<Scorecombinatie> combinaties = new List<Scorecombinatie>();
            foreach (Scorecombinatie c in geefCombinaties())
            {
                if (c.isVrij())
                {
                    combinaties.Add(c);
                }
            }
            return (Scorecombinatie[])combinaties.ToArray();
        }

        public void vulCombinatieIn(Scorecombinatie combinatie)
        {
            laatsteBeurt().setScorecombinatie(combinatie);
        }

        public bool spelNietAfgelopen()
        {
            return geefVrijeCombinaties().Length > 0;
        }

        public int getHuidigeWorpnr()
        {
            return laatsteBeurt().getWorpNr();
        }

        public int getHuidigeBeurtnr()
        {
            return laatsteBeurt().getBeurtnr();
        }

        public int getTotaalScore()
        {
            return bovensteSectie.getScore() + ondersteSectie.getScore();
        }

        public void print(TextWriter output)
        {
            output.WriteLine("Yahtzee   ----------------------------------------");
            foreach (Beurt b in beurten)
            {
                b.print(output);
            }
            output.WriteLine("Resultaat ----------------------------------------");
            bovensteSectie.print(output);
            output.WriteLine("   -------");
            ondersteSectie.print(output);
            output.Write("  totaal boven: {0,10}", bovensteSectie.getScore());
            output.WriteLine();
            output.WriteLine("                      ---- +");
            output.Write("  totaal:{0,17}", this.getTotaalScore());
            output.WriteLine();
        }
    }
}